package mark.tom.narcissus;

import android.content.Context;

import java.util.Map;
import java.util.Set;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import mark.tom.narcissus.template.IComponents;
import mark.tom.narcissus.template.ILogWatcher;
import mark.tom.narcissus.template.IModuleFilter;

/**
 * @Description: 自定义组件初始化入口
 * @Author: Tom.Shen
 * @Package: mark.tom.narcissus
 * @Date: 2020/9/28
 * @Copyright: 版权归 Mark 所有
 */
public final class Narcissus {

    protected Context mContext;
    protected Logger mLogger;
    protected IModuleFilter mFilter;

    /**
     * @Description: 获取注册在Manifest中的数据, 以便上层扩展
     * @Author: Tom.Shen
     * @Date: 2020/10/16
     */
    public Map<String, IComponents> get() {
        return new ManifestParser(mContext, mLogger, mFilter).parse();
    }

    /**
     * @Description: 得到注册数据直接初始化
     * @Author: Tom.Shen
     * @Date: 2020/10/16
     */
    public void init() {
        Map<String, IComponents> components = get();
        if (null == components || 0 == components.size()) {
            mLogger.d("No Components Need Init");
            return;
        }
        long startTime;
        Set<Map.Entry<String, IComponents>> entrySet = components.entrySet();
        for (Map.Entry<String, IComponents> tmp : entrySet) {
            startTime = System.currentTimeMillis();
            mLogger.d("-------------------------------------------------------------------------");
            try {
                tmp.getValue().registerComponents(mContext);
                mLogger.i("Module : " + tmp.getKey() + " Init Success. Cost Time : " + (System.currentTimeMillis() - startTime) + "ms");
            } catch (Exception ex) {
                mLogger.i("Module : " + tmp.getKey() + " Init Fail. Exception : " + ex.getMessage());
            }
            mLogger.d("-------------------------------------------------------------------------");
        }
    }

    public static final class NarcissusBuilder {

        private final Context mContext;
        private ILogWatcher mLogger;
        private IModuleFilter mFilter;

        private NarcissusBuilder(@NonNull Context mContext) {
            this.mContext = mContext;
        }

        public static NarcissusBuilder get(@NonNull Context mContext) {
            return new NarcissusBuilder(mContext);
        }

        public NarcissusBuilder with(@Nullable ILogWatcher mLogger) {
            this.mLogger = mLogger;
            return this;
        }

        public NarcissusBuilder with(@Nullable IModuleFilter mFilter) {
            this.mFilter = mFilter;
            return this;
        }

        public Narcissus build() {
            Narcissus narcissus = new Narcissus();
            narcissus.mContext = this.mContext;
            narcissus.mLogger = new Logger(this.mLogger);
            narcissus.mFilter = this.mFilter;
            return narcissus;
        }
    }
}
